package com.kyle.dao.base;


import java.lang
.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.SessionFactory;

import com.kyle.entity.util.PageBean;


@SuppressWarnings("unchecked")
public abstract class BaseDaoImpl<T> implements BaseDao<T> {

	@Resource
	private SessionFactory sf ;
	
	private Class<T> clazz ;
	
	public BaseDaoImpl() {
		
		Class c = getClass();
		Type t = c.getGenericSuperclass();
		if (t instanceof ParameterizedType) {
			ParameterizedType type = (ParameterizedType) this.getClass()
					.getGenericSuperclass();
			clazz = (Class<T>) type.getActualTypeArguments()[0];
		}		
	}

	public void saveEntity(T t) {
		sf.getCurrentSession().save(t);
	}

	public void updateEntity(T t) {
		sf.getCurrentSession().update(t);
	}

	public void saveOrUpdateEntity(T t) {
		sf.getCurrentSession().saveOrUpdate(t);
	}

	public void deleteEntity(T t) {
		sf.getCurrentSession().delete(t);
	}

	public void batchEntityByHQL(String hql, Object... objects) {
		Query q = sf.getCurrentSession().createQuery(hql);
		for(int i = 0 ; i < objects.length ; i ++){
			q.setParameter(i, objects[i]);
		}
		q.executeUpdate();
	}
	
	public void executeSQL(String sql,Object...objects){
		SQLQuery q = sf.getCurrentSession().createSQLQuery(sql);
		for(int i = 0 ; i < objects.length ; i ++){
			q.setParameter(i, objects[i]);
		}
		q.executeUpdate();
	}

	//get
	public T getEntity(Integer id) {
		return (T) sf.getCurrentSession().get(clazz, id);
	}

	//load
	public T loadEntity(Integer id) {
		return (T) sf.getCurrentSession().load(clazz, id);
	}
	
	public List<T> getAllEntry() {
		// TODO Auto-generated method stub
		
		return this.findEntityByHQL("from "+this.clazz.getName());
	}
	
	public List<T> findEntityByHQL(String hql, Object... objects) {
		Query q = sf.getCurrentSession().createQuery(hql);
		for(int i = 0 ; i < objects.length ; i ++){
			q.setParameter(i, objects[i]);
		}
		
		return q.list();
	}
	
	public List<T> findEntityByHQL(String hql, Object objects[],PageBean pageBean) {
		Query q = sf.getCurrentSession().createQuery(hql);
		for(int i = 0 ; objects!=null && i < objects.length ; i ++){
			q.setParameter(i, objects[i]);
		}
		if(pageBean!=null){
			q.setFirstResult(pageBean.getPage()-1);
			q.setMaxResults(pageBean.getRows());
		}
		return q.list();
	}
	
	public Object uniqueResult(String hql,Object...objects){
		Query q = sf.getCurrentSession().createQuery(hql);
		for(int i = 0 ; objects!=null && i < objects.length ; i ++){
			q.setParameter(i, objects[i]);
		}
		return q.uniqueResult();
	}
	
	public List<T> findObjectBySQL(String sql,Object...objects){
		SQLQuery q = sf.getCurrentSession().createSQLQuery(sql);
		for(int i = 0 ; i < objects.length ; i ++){
			q.setParameter(i, objects[i]);
		}

		q.addEntity(clazz);
		return q.list();
	}

	
	/**
	 * 得到指定表的分页
	 * xiakai
	 * @param pageBean
	 * @param wherejpql
	 * @param queryParams
	 * @param orderby
	 * @return
	 */
	public List getScrollData(PageBean pageBean,String wherejpql, Object[] queryParams,LinkedHashMap<String, String> orderby) {
		String entityname = clazz.getName();
		List list = findEntityByHQL("from "+entityname+" o "+(wherejpql==null || "".equals(wherejpql.trim())? "": "where "+ wherejpql)+ buildOrderby(orderby), queryParams, pageBean);
		return list;
	}
	
	/**
	 * 得到指定的数据的count
	 * @return
	 * xiakai
	 */
	public Object getScrollDataCount(String wherejpql, Object[] queryParams){
		String entityname = clazz.getName();
		return this.uniqueResult("select count(*) from "+ entityname+ " o "+(wherejpql==null || "".equals(wherejpql.trim())? "": "where "+ wherejpql),queryParams);
	}
	
	protected static String buildOrderby(LinkedHashMap<String, String> orderby){
		StringBuffer orderbyql = new StringBuffer("");
		if(orderby!=null && orderby.size()>0){
			orderbyql.append(" order by ");
			for(String key : orderby.keySet()){
				orderbyql.append("o.").append(key).append(" ").append(orderby.get(key)).append(",");
			}
			orderbyql.deleteCharAt(orderbyql.length()-1);
		}
		return orderbyql.toString();
	}
}
